#pragma once

#include <iostream>
#include <string>
#include <cstdio>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdalign.h>
#include <unistd.h>

const std::string gpath = "/home/lighthouse/112";
int gprojId = 0x6666;
// 操作系统，申请空间，是按照块为单位：4kb 1kb
int gshmsize = 4096; // 共享内存大小，建议使用 4096 的整数倍
mode_t gmode = 0600;

// std::string ToHex(key_t k)
// {
//     char buffer[64];
//     // 按照 16 进制 把 k  转到 buffer 里面
//     snprintf(buffer, sizeof(buffer), "0x%x", k);
//     return buffer;
// }


class ShareMemory
{
private:
    void CreateShmHelper(int shmflg)
    {
        _key = ::ftok(gpath.c_str(), gprojId);
        if(_key < 0)
        {
            std::cerr << "ftok error"  << std::endl;
            return ;
        }
        _shmid = ::shmget(_key, gshmsize, shmflg);
        if(_shmid < 0)
        {
            std::cerr << "shmget error" << std::endl;
            return ;
        }
        std::cout << "shmid: " << _shmid << std::endl;
    }

public:
    ShareMemory():_shmid(-1), _key(0), _addr(nullptr)
    {
    
    }
    ~ShareMemory()
    {

    }
    void CreateShm()
    {
        if(_shmid == -1)
            CreateShmHelper(IPC_CREAT | IPC_EXCL | gmode);

    }
    void GetShm()
    {
        CreateShmHelper(IPC_CREAT);
    }
    void AttachShm()
    {
        _addr = shmat(_shmid, nullptr, 0);
        if((long long) _addr == -1)
        {
            std::cout << "attach error" << std::endl;
        }
    }
    void DetachShm()
    {
        if(_addr != nullptr)
            ::shmdt(_addr);
        std::cout << "detach done " << std::endl; 
    }
    void DeleteShm()
    {
        shmctl(_shmid, IPC_RMID, nullptr);
    }

    void *GetAddr()
    {
        return _addr;
    }

    void ShmMeta()
    {
    }

private: //写时拷贝，系统上会自己去区分的
    int _shmid;
    key_t _key;
    void *_addr;
    int _size;
};

ShareMemory shm;


struct data
{
    char status[32];
    char lasttime[48];
    char image[4000];
};